#include "../include/jcChromaKey.h"
#include "../include/jcSegmentador.h"
#include "../include/jcHSV.h"
#include "../include/jcTratadorDeBorda.h"
#include "../include/jcIluminacao.h"
#include <stdio.h>


jcChromaKey::jcChromaKey()
{

};

jcChromaKey::~jcChromaKey()
{

};

void jcChromaKey::jcMergeRGB(IplImage* foreground, IplImage* background, IplImage* mergeimg)
{
     jcSegmentador Seg;
     
     Seg.jcColorBinarizador(foreground,mergeimg);
     
     int R, G, B;
     int Linhas= mergeimg->height;
     int Colunas= mergeimg->width;
     
     for (int y=0; y<Linhas; y++){
        for (int x=0; x<Colunas; x++){
            R=((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+2];
            G=((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+1];
            B=((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+0];
            if((R<10)&&(G<10)&&(B<10))
            {
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+2]=((uchar*)(background->imageData + background->widthStep*y))[x*3+2];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+1]=((uchar*)(background->imageData + background->widthStep*y))[x*3+1];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+0]=((uchar*)(background->imageData + background->widthStep*y))[x*3+0];
            } else {
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+2]=((uchar*)(foreground->imageData + foreground->widthStep*y))[x*3+2];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+1]=((uchar*)(foreground->imageData + foreground->widthStep*y))[x*3+1];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+0]=((uchar*)(foreground->imageData + foreground->widthStep*y))[x*3+0]; 
            }
        }
     }
}

void jcChromaKey::jcMergeHSV(IplImage* foreground, IplImage* background, IplImage* mergeimg)
{
     jcHSV HSV;
     IplImage* hsvtmp = cvCreateImage(cvGetSize(foreground),8,3);
     HSV.jcHSVSegmentation(foreground,hsvtmp);
     
     float h,s,v;
     int Linhas= foreground->height;
     int Colunas= foreground->width;
     
     for (int y=0; y<Linhas; y++){
        for (int x=0; x<Colunas; x++){
            v=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+2];
            s=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+1];
            h=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+0];
            if((h==0)&&(s==0)&&(v==0))
            {
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+2]=((uchar*)(background->imageData + background->widthStep*y))[x*3+2];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+1]=((uchar*)(background->imageData + background->widthStep*y))[x*3+1];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+0]=((uchar*)(background->imageData + background->widthStep*y))[x*3+0];
            } else {
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+2]=((uchar*)(foreground->imageData + foreground->widthStep*y))[x*3+2];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+1]=((uchar*)(foreground->imageData + foreground->widthStep*y))[x*3+1];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+0]=((uchar*)(foreground->imageData + foreground->widthStep*y))[x*3+0]; 
            }
        }
     }
     cvReleaseImage(&hsvtmp);
}

void jcChromaKey::jcMergeHSVGaussiana(IplImage* foreground, IplImage* background, IplImage* mergeimg)
{
     jcHSV HSV;
     jcTratadorDeBorda Borda;
     jcIluminacao Ilum;
     
     IplImage* hsvtmp = cvCreateImage(cvGetSize(foreground),8,3);
     HSV.jcHSVSegmentation(foreground,hsvtmp);
     Borda.GetMaxArea(hsvtmp, CV_FILLED);
     
     int R,G,B;
     int Linhas= foreground->height;
     int Colunas= foreground->width;
     
     for (int y=0; y<Linhas; y++)
     {
        for (int x=0; x<Colunas; x++)
        {
            R=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+2];
            G=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+1];
            B=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+0];
            if((R==0)&&(G==0)&&(B==0))
            {
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+2]=((uchar*)(background->imageData + background->widthStep*y))[x*3+2];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+1]=((uchar*)(background->imageData + background->widthStep*y))[x*3+1];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+0]=((uchar*)(background->imageData + background->widthStep*y))[x*3+0];
            } else {
                //Ilum.jcIncorporaLuz(background, foreground, x, y);
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+2]=((uchar*)(foreground->imageData + foreground->widthStep*y))[x*3+2];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+1]=((uchar*)(foreground->imageData + foreground->widthStep*y))[x*3+1];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+0]=((uchar*)(foreground->imageData + foreground->widthStep*y))[x*3+0]; 
            }
        }
     }
     Borda.GetMaxArea(hsvtmp, 3);
     for (int y=2; y<(Linhas-2); y++)
     {
        for (int x=2; x<(Colunas-2); x++)
        {
            R=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+2];
            G=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+1];
            B=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+0];
            if((R==255)&&(G==255)&&(B==255))
            {
               Borda.jcGaussiana( mergeimg, x, y);
            }
        }
     }
     cvReleaseImage(&hsvtmp);
}


void jcChromaKey::jcMergeHSVBWGaussiana(IplImage* foreground, IplImage* background, IplImage* mergeimg)
{
     jcHSV HSV;
     jcTratadorDeBorda Borda;
     
     IplImage* hsvtmp = cvCreateImage(cvGetSize(foreground),8,3);
     HSV.jcHSVSegmentation(foreground,hsvtmp);
     Borda.GetMaxArea(hsvtmp, CV_FILLED);
     
     int R,G,B;
     int Linhas= foreground->height;
     int Colunas= foreground->width;
     
     for (int y=0; y<Linhas; y++)
     {
        for (int x=0; x<Colunas; x++)
        {
            R=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+2];
            G=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+1];
            B=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+0];
            if((R==0)&&(G==0)&&(B==0))
            {
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+2]=((uchar*)(background->imageData + background->widthStep*y))[x*3+2];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+1]=((uchar*)(background->imageData + background->widthStep*y))[x*3+1];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+0]=((uchar*)(background->imageData + background->widthStep*y))[x*3+0];
            } else {
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+2]=((uchar*)(foreground->imageData + foreground->widthStep*y))[x*3+2];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+1]=((uchar*)(foreground->imageData + foreground->widthStep*y))[x*3+1];
                ((uchar*)(mergeimg->imageData + mergeimg->widthStep*y))[x*3+0]=((uchar*)(foreground->imageData + foreground->widthStep*y))[x*3+0]; 
            }
        }
     }
     Borda.GetMaxArea(hsvtmp, 6);
     for (int y=2; y<(Linhas-2); y++)
     {
        for (int x=2; x<(Colunas-2); x++)
        {
            R=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+2];
            G=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+1];
            B=((uchar*)(hsvtmp->imageData + hsvtmp->widthStep*y))[x*3+0];
            if((R==255)&&(G==255)&&(B==255))
            {
               Borda.jcGaussiana( mergeimg, x, y);
            }
        }
     }
     cvReleaseImage(&hsvtmp);
}

